/*
 * Galaxium Messenger
 * Copyright (C) 2008 Paul Burton <paulburton89@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;

using Gdk;
using Gtk;

namespace Galaxium.Gui.GtkGui
{
	public delegate void SelectedDelegate<T> (object sender, T val);
	
	public class SelectionPopupDialog<T> : Gtk.Window
	{
		public event SelectedDelegate<T> Selected;
		
		VBox _vBox;
		IconView _iView;
		ListStore _store;
		
		protected IconView IconView
		{
			get { return _iView; }
		}
		
		protected SelectionPopupDialog ()
			: base (Gtk.WindowType.Toplevel)
		{
			TypeHint = WindowTypeHint.Utility;
			Decorated = false;
			FocusOnMap = true;
			Gravity = Gdk.Gravity.Static;
			Resizable = false;
			SkipPagerHint = true;
			SkipTaskbarHint = true;
			WindowPosition = WindowPosition.Mouse;
			
			FocusOutEvent += delegate { Destroy (); };
		}
		
		protected virtual void Initialize ()
		{
			Frame frame = new Frame ();
			frame.Shadow = ShadowType.Out;
			
			_vBox = new VBox ();
			_vBox.BorderWidth = 5;
			_vBox.Spacing = 5;
			
			_iView = new IconView ();
			_iView.Orientation = Orientation.Horizontal;
			
			_store = new ListStore (typeof (Pixbuf), typeof (T));
			PopulateModel (_store);
			
			_iView.Model = _store;
			_iView.PixbufColumn = 0;
			_iView.TextColumn = -1;
			_iView.SelectionChanged += SelectionChanged;
			_iView.ItemActivated += ItemActivated;
			
			ScrolledWindow sw = new ScrolledWindow ();
			sw.ShadowType = ShadowType.In;
			sw.HscrollbarPolicy = PolicyType.Never;
			sw.VscrollbarPolicy = PolicyType.Never;
			
			sw.Add (_iView);
			_vBox.Add (sw);
			
			AddCustomControls (_vBox);
			
			frame.Add (_vBox);
			Add (frame);
		}
		
		protected virtual void AddCustomControls (VBox vbox)
		{
		}
		
		protected virtual void PopulateModel (ListStore store)
		{
		}
		
		public new void Show ()
		{
			Initialize ();
			ShowAll ();
			Present ();
		}
		
		public void Show (int x, int y)
		{
			Initialize ();
			
			SizeAllocated += delegate (object sender, SizeAllocatedArgs args)
			{
				x -= (args.Allocation.Width / 2);
				y -= (args.Allocation.Height / 2);
				
				if (x < 0)
					x = 0;
				if (x > Screen.Width - args.Allocation.Width)
					x = Screen.Width - args.Allocation.Width;
				if (y < 0)
					y = 0;
				if (y > Screen.Height - args.Allocation.Height)
					y = Screen.Height - args.Allocation.Height;
				
				Move (x, y);
			};
			
			ShowAll ();
			Present ();
		}
		
		void SelectionChanged (object sender, EventArgs args)
		{
			_iView.ActivateItem (_iView.SelectedItems[0]);
		}
		
		void ItemActivated (object sender, ItemActivatedArgs args)
		{
			TreeIter iter;
			_store.GetIter (out iter, args.Path);
			T val = (T)_store.GetValue (iter, 1);
			
			if (val != null)
				OnSelected (val);
			
			Hide ();
		}
		
		protected virtual void OnSelected (T val)
		{
			if (Selected != null)
				Selected (this, val);
		}
	}
}
